Load packages

library(tidyverse)
── Attaching core tidyverse packages ────── tidyverse 2.0.0 ──
✔ dplyr     1.1.2     ✔ readr     2.1.4
✔ forcats   1.0.0     ✔ stringr   1.5.0
✔ ggplot2   3.4.2     ✔ tibble    3.2.1
✔ lubridate 1.9.2     ✔ tidyr     1.3.0
✔ purrr     1.0.1     ── Conflicts ──────────────────────── tidyverse_conflicts() ──
✖ dplyr::filter() masks stats::filter()
✖ dplyr::lag()    masks stats::lag()
ℹ Use the ]8;;http://conflicted.r-lib.org/conflicted package]8;; to force all conflicts to become errors
library(lubridate)
library(hms)

Attaching package: ‘hms’

The following object is masked from ‘package:lubridate’:

    hms
#library(googlesheets4)
library(readxl)

#gs4_deauth()
#ppl_15mins <- read_sheet("https://docs.google.com/spreadsheets/d/1uv5SBYklQ-bArCnWPVG1hOvKu3fpgD1sgU8bTZ8sR5o/edit?usp=sharing")
#add column types


col_datatypes <- c('numeric','numeric','date','text',rep('numeric',99))

#?read_excel

hourly1 <- read_excel("Hourly Usage 220326 to 220624.xlsx", col_types = col_datatypes)
Warning: Expecting numeric in A277 / R277C1: got 'The information contained in this file is intended for the confidential use by the customer and third parties authorized by the customer to receive the information. Any unauthorized use is prohibited.'
hourly2 <- read_excel("Hourly Usage 220625 to 230623.xlsx", col_types = col_datatypes)
Warning: Expecting numeric in A1096 / R1096C1: got 'The information contained in this file is intended for the confidential use by the customer and third parties authorized by the customer to receive the information. Any unauthorized use is prohibited.'
hourly3 <- read_excel("PPL 230624 to 240509.xlsx", col_types = col_datatypes)
Warning: Expecting numeric in A967 / R967C1: got 'The information contained in this file is intended for the confidential use by the customer and third parties authorized by the customer to receive the information. Any unauthorized use is prohibited.'
hourly1
hourly2
hourly3

ppl_15mins <- bind_rows(hourly1,list(hourly2,hourly3))

ppl_15mins %>% arrange(desc(Date), `Read Type`)
NA
NA
#ppl_15mins <- ppl_15mins %>% rename(date = Date)

hourly_ppl_pivot <- ppl_15mins %>% 
  rename(date = Date) %>% 
  pivot_longer(!c("Account Number", "Meter Number", date, "Read Type", Min, Max, Total), names_to = "time", values_to = "kWh") 

#ppl_15mins %>%  mutate(date = as_date(Date)) 

rename(ppl_15mins, date = Date)

#rm(hourly_pivot)

hourly_ppl_pivot <- hourly_ppl_pivot %>% 
  mutate(time = parse_time(time, '%H:%M %p'), month = month(date, label=TRUE), year = year(date), yday = yday(date), wday = wday(date, label=TRUE))

(hourly_ppl_net <- hourly_ppl_pivot %>% 
  filter(`Read Type` == "kWh Net"))

Import solar production from another notebook (EnphaseHourly.Rmd)

ggplot(hourly_production, aes(datetime, energy_produced_Wh)) +
  geom_point()


ggplot(hourly_production, aes(time, energy_produced_Wh)) +
  theme(axis.text.x = element_text(angle = 90)) +
  geom_point()

Net + Produced = Consumedggplot(hourly_production, aes(datetime, energy_produced_Wh)) +

geom_point()

ggplot(hourly_production, aes(time, energy_produced_Wh)) +

theme(axis.text.x = element_text(angle = 90)) +

geom_point()


# hourly_ppl_net <- hourly_ppl_net %>% mutate(date = as_date(date))

hourly_ppl_net %>% arrange(desc(date))
hourly_production %>% arrange(desc(date))


(hourly_electricity <- hourly_ppl_net %>% 
    inner_join(hourly_production, by = join_by(date,time))  %>% 
    mutate(consumed_kWh = kWh + energy_produced_Wh/1000, produced_kWh = energy_produced_Wh/1000)  %>% 
    rename(net_kWh = kWh) %>% 
    select(datetime, date, time, net_kWh, produced_kWh, consumed_kWh))
NA
ggplot(hourly_electricity, aes(x=time)) +
  geom_point(aes(y=consumed_kWh,color="red")) 


ggplot(hourly_electricity, aes(x=datetime)) +
  geom_point(aes(y=consumed_kWh,color="red")) 


hourly_electricity %>% summarize(min_date = min(date), max_date = max(date))

electricity_by_time <- hourly_electricity %>% 
  filter(date <= as.POSIXct('12/31/2022 00:00',format="%m/%d/%Y %H:%M",tz=Sys.timezone()) ) %>% 
  group_by(time) %>% 
  summarize(produced_kWh = mean(produced_kWh), consumed_kWh = mean(consumed_kWh), net_kWh = mean(net_kWh)) %>% 
  arrange(time)

electricity_by_time

ggplot(electricity_by_time, aes(x=time)) +
  geom_point(aes(y=consumed_kWh, color="Consumed")) +
  geom_point(aes(y=net_kWh, color="Net")) +
  geom_point(aes(y=produced_kWh*-1, color="Produced")) +
  labs(colour="",x="Time of Day",y="Electricity Consumption (kWh)")+
  scale_color_manual(values = c("red","black","green")) +
  ggtitle("Home Electricity in 15-Minute Intervals (Apr 15 - Dec 31, 2022)")

electricity_by_month_time <- hourly_electricity %>% 
  mutate(month = as_factor(month(date))) %>% 
  filter(date <= as.POSIXct('12/31/2022 00:00',format="%m/%d/%Y %H:%M",tz=Sys.timezone()) ) %>% 
  group_by(month, time) %>% 
  summarize(produced_kWh = mean(produced_kWh), consumed_kWh = mean(consumed_kWh), net_kWh = mean(net_kWh)) %>% 
  arrange(month, time)
`summarise()` has grouped output by 'month'. You can override using the `.groups` argument.
ggplot(electricity_by_month_time, aes(time, consumed_kWh, group=month, color=month)) +
  geom_point() +
  ggtitle("Home Electricity in 15-Minute Intervals (Apr 15 - Dec 31, 2022)") +
  ylab("Net Electricity Consumption (kWh)")

NA
NA

Example day with EV charging

#hourly_electricity

march23 <- hourly_electricity %>% 
  filter(date >= "2023-04-01" & date < "2023-04-06")

ggplot(march23) +
  geom_point(aes(datetime,net_kWh))



ggplot(march23) +
  geom_point(aes(time,net_kWh, color = factor(date)))

LS0tCnRpdGxlOiAiSG91cmx5IEVsZWN0cmljaXR5IENvbnN1bXB0aW9uIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgpMb2FkIHBhY2thZ2VzCmBgYHtyfQpsaWJyYXJ5KHRpZHl2ZXJzZSkKbGlicmFyeShsdWJyaWRhdGUpCmxpYnJhcnkoaG1zKQojbGlicmFyeShnb29nbGVzaGVldHM0KQpsaWJyYXJ5KHJlYWR4bCkKYGBgCgoKYGBge3J9CgojZ3M0X2RlYXV0aCgpCiNwcGxfMTVtaW5zIDwtIHJlYWRfc2hlZXQoImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzF1djVTQllrbFEtYkFyQ25XUFZHMWhPdkt1M2ZwZ0Qxc2dVOGJUWjhzUjVvL2VkaXQ/dXNwPXNoYXJpbmciKQojYWRkIGNvbHVtbiB0eXBlcwoKCmNvbF9kYXRhdHlwZXMgPC0gYygnbnVtZXJpYycsJ251bWVyaWMnLCdkYXRlJywndGV4dCcscmVwKCdudW1lcmljJyw5OSkpCgojP3JlYWRfZXhjZWwKCmhvdXJseTEgPC0gcmVhZF9leGNlbCgiSG91cmx5IFVzYWdlIDIyMDMyNiB0byAyMjA2MjQueGxzeCIsIGNvbF90eXBlcyA9IGNvbF9kYXRhdHlwZXMpCmhvdXJseTIgPC0gcmVhZF9leGNlbCgiSG91cmx5IFVzYWdlIDIyMDYyNSB0byAyMzA2MjMueGxzeCIsIGNvbF90eXBlcyA9IGNvbF9kYXRhdHlwZXMpCmhvdXJseTMgPC0gcmVhZF9leGNlbCgiUFBMIDIzMDYyNCB0byAyNDA1MDkueGxzeCIsIGNvbF90eXBlcyA9IGNvbF9kYXRhdHlwZXMpCgpob3VybHkxCmhvdXJseTIKaG91cmx5MwoKcHBsXzE1bWlucyA8LSBiaW5kX3Jvd3MoaG91cmx5MSxsaXN0KGhvdXJseTIsaG91cmx5MykpCgpwcGxfMTVtaW5zICU+JSBhcnJhbmdlKGRlc2MoRGF0ZSksIGBSZWFkIFR5cGVgKQoKCmBgYAoKCmBgYHtyfQojcHBsXzE1bWlucyA8LSBwcGxfMTVtaW5zICU+JSByZW5hbWUoZGF0ZSA9IERhdGUpCgpob3VybHlfcHBsX3Bpdm90IDwtIHBwbF8xNW1pbnMgJT4lIAogIHJlbmFtZShkYXRlID0gRGF0ZSkgJT4lIAogIHBpdm90X2xvbmdlcighYygiQWNjb3VudCBOdW1iZXIiLCAiTWV0ZXIgTnVtYmVyIiwgZGF0ZSwgIlJlYWQgVHlwZSIsIE1pbiwgTWF4LCBUb3RhbCksIG5hbWVzX3RvID0gInRpbWUiLCB2YWx1ZXNfdG8gPSAia1doIikgCgojcHBsXzE1bWlucyAlPiUgIG11dGF0ZShkYXRlID0gYXNfZGF0ZShEYXRlKSkgCgpyZW5hbWUocHBsXzE1bWlucywgZGF0ZSA9IERhdGUpCgojcm0oaG91cmx5X3Bpdm90KQoKaG91cmx5X3BwbF9waXZvdCA8LSBob3VybHlfcHBsX3Bpdm90ICU+JSAKICBtdXRhdGUodGltZSA9IHBhcnNlX3RpbWUodGltZSwgJyVIOiVNICVwJyksIG1vbnRoID0gbW9udGgoZGF0ZSwgbGFiZWw9VFJVRSksIHllYXIgPSB5ZWFyKGRhdGUpLCB5ZGF5ID0geWRheShkYXRlKSwgd2RheSA9IHdkYXkoZGF0ZSwgbGFiZWw9VFJVRSkpCgooaG91cmx5X3BwbF9uZXQgPC0gaG91cmx5X3BwbF9waXZvdCAlPiUgCiAgZmlsdGVyKGBSZWFkIFR5cGVgID09ICJrV2ggTmV0IikpCmBgYAoKSW1wb3J0IHNvbGFyIHByb2R1Y3Rpb24gZnJvbSBhbm90aGVyIG5vdGVib29rIChFbnBoYXNlSG91cmx5LlJtZCkKCmBgYHtyfQpnZ3Bsb3QoaG91cmx5X3Byb2R1Y3Rpb24sIGFlcyhkYXRldGltZSwgZW5lcmd5X3Byb2R1Y2VkX1doKSkgKwogIGdlb21fcG9pbnQoKQoKZ2dwbG90KGhvdXJseV9wcm9kdWN0aW9uLCBhZXModGltZSwgZW5lcmd5X3Byb2R1Y2VkX1doKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gOTApKSArCiAgZ2VvbV9wb2ludCgpCmBgYAoKTmV0ICsgUHJvZHVjZWQgPSBDb25zdW1lZGdncGxvdChob3VybHlfcHJvZHVjdGlvbiwgYWVzKGRhdGV0aW1lLCBlbmVyZ3lfcHJvZHVjZWRfV2gpKSArCgogIGdlb21fcG9pbnQoKQoKZ2dwbG90KGhvdXJseV9wcm9kdWN0aW9uLCBhZXModGltZSwgZW5lcmd5X3Byb2R1Y2VkX1doKSkgKwoKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDkwKSkgKwoKICBnZW9tX3BvaW50KCkKYGBge3J9CgojIGhvdXJseV9wcGxfbmV0IDwtIGhvdXJseV9wcGxfbmV0ICU+JSBtdXRhdGUoZGF0ZSA9IGFzX2RhdGUoZGF0ZSkpCgpob3VybHlfcHBsX25ldCAlPiUgYXJyYW5nZShkZXNjKGRhdGUpKQpob3VybHlfcHJvZHVjdGlvbiAlPiUgYXJyYW5nZShkZXNjKGRhdGUpKQoKCihob3VybHlfZWxlY3RyaWNpdHkgPC0gaG91cmx5X3BwbF9uZXQgJT4lIAogICAgaW5uZXJfam9pbihob3VybHlfcHJvZHVjdGlvbiwgYnkgPSBqb2luX2J5KGRhdGUsdGltZSkpICAlPiUgCiAgICBtdXRhdGUoY29uc3VtZWRfa1doID0ga1doICsgZW5lcmd5X3Byb2R1Y2VkX1doLzEwMDAsIHByb2R1Y2VkX2tXaCA9IGVuZXJneV9wcm9kdWNlZF9XaC8xMDAwKSAgJT4lIAogICAgcmVuYW1lKG5ldF9rV2ggPSBrV2gpICU+JSAKICAgIHNlbGVjdChkYXRldGltZSwgZGF0ZSwgdGltZSwgbmV0X2tXaCwgcHJvZHVjZWRfa1doLCBjb25zdW1lZF9rV2gpKQoKYGBgCgpgYGB7cn0KZ2dwbG90KGhvdXJseV9lbGVjdHJpY2l0eSwgYWVzKHg9dGltZSkpICsKICBnZW9tX3BvaW50KGFlcyh5PWNvbnN1bWVkX2tXaCxjb2xvcj0icmVkIikpIAoKZ2dwbG90KGhvdXJseV9lbGVjdHJpY2l0eSwgYWVzKHg9ZGF0ZXRpbWUpKSArCiAgZ2VvbV9wb2ludChhZXMoeT1jb25zdW1lZF9rV2gsY29sb3I9InJlZCIpKSAKYGBgCgpgYGB7cn0KCmhvdXJseV9lbGVjdHJpY2l0eSAlPiUgc3VtbWFyaXplKG1pbl9kYXRlID0gbWluKGRhdGUpLCBtYXhfZGF0ZSA9IG1heChkYXRlKSkKCmVsZWN0cmljaXR5X2J5X3RpbWUgPC0gaG91cmx5X2VsZWN0cmljaXR5ICU+JSAKICBmaWx0ZXIoZGF0ZSA8PSBhcy5QT1NJWGN0KCcxMi8zMS8yMDIyIDAwOjAwJyxmb3JtYXQ9IiVtLyVkLyVZICVIOiVNIix0ej1TeXMudGltZXpvbmUoKSkgKSAlPiUgCiAgZ3JvdXBfYnkodGltZSkgJT4lIAogIHN1bW1hcml6ZShwcm9kdWNlZF9rV2ggPSBtZWFuKHByb2R1Y2VkX2tXaCksIGNvbnN1bWVkX2tXaCA9IG1lYW4oY29uc3VtZWRfa1doKSwgbmV0X2tXaCA9IG1lYW4obmV0X2tXaCkpICU+JSAKICBhcnJhbmdlKHRpbWUpCgplbGVjdHJpY2l0eV9ieV90aW1lCgpnZ3Bsb3QoZWxlY3RyaWNpdHlfYnlfdGltZSwgYWVzKHg9dGltZSkpICsKICBnZW9tX3BvaW50KGFlcyh5PWNvbnN1bWVkX2tXaCwgY29sb3I9IkNvbnN1bWVkIikpICsKICBnZW9tX3BvaW50KGFlcyh5PW5ldF9rV2gsIGNvbG9yPSJOZXQiKSkgKwogIGdlb21fcG9pbnQoYWVzKHk9cHJvZHVjZWRfa1doKi0xLCBjb2xvcj0iUHJvZHVjZWQiKSkgKwogIGxhYnMoY29sb3VyPSIiLHg9IlRpbWUgb2YgRGF5Iix5PSJFbGVjdHJpY2l0eSBDb25zdW1wdGlvbiAoa1doKSIpKwogIHNjYWxlX2NvbG9yX21hbnVhbCh2YWx1ZXMgPSBjKCJyZWQiLCJibGFjayIsImdyZWVuIikpICsKICBnZ3RpdGxlKCJIb21lIEVsZWN0cmljaXR5IGluIDE1LU1pbnV0ZSBJbnRlcnZhbHMgKEFwciAxNSAtIERlYyAzMSwgMjAyMikiKQoKYGBgCgoKYGBge3J9CmVsZWN0cmljaXR5X2J5X21vbnRoX3RpbWUgPC0gaG91cmx5X2VsZWN0cmljaXR5ICU+JSAKICBtdXRhdGUobW9udGggPSBhc19mYWN0b3IobW9udGgoZGF0ZSkpKSAlPiUgCiAgZmlsdGVyKGRhdGUgPD0gYXMuUE9TSVhjdCgnMTIvMzEvMjAyMiAwMDowMCcsZm9ybWF0PSIlbS8lZC8lWSAlSDolTSIsdHo9U3lzLnRpbWV6b25lKCkpICkgJT4lIAogIGdyb3VwX2J5KG1vbnRoLCB0aW1lKSAlPiUgCiAgc3VtbWFyaXplKHByb2R1Y2VkX2tXaCA9IG1lYW4ocHJvZHVjZWRfa1doKSwgY29uc3VtZWRfa1doID0gbWVhbihjb25zdW1lZF9rV2gpLCBuZXRfa1doID0gbWVhbihuZXRfa1doKSkgJT4lIAogIGFycmFuZ2UobW9udGgsIHRpbWUpCgpnZ3Bsb3QoZWxlY3RyaWNpdHlfYnlfbW9udGhfdGltZSwgYWVzKHRpbWUsIGNvbnN1bWVkX2tXaCwgZ3JvdXA9bW9udGgsIGNvbG9yPW1vbnRoKSkgKwogIGdlb21fcG9pbnQoKSArCiAgZ2d0aXRsZSgiSG9tZSBFbGVjdHJpY2l0eSBpbiAxNS1NaW51dGUgSW50ZXJ2YWxzIChBcHIgMTUgLSBEZWMgMzEsIDIwMjIpIikgKwogIHlsYWIoIk5ldCBFbGVjdHJpY2l0eSBDb25zdW1wdGlvbiAoa1doKSIpCgoKYGBgCgpFeGFtcGxlIGRheSB3aXRoIEVWIGNoYXJnaW5nCgpgYGB7cn0KI2hvdXJseV9lbGVjdHJpY2l0eQoKbWFyY2gyMyA8LSBob3VybHlfZWxlY3RyaWNpdHkgJT4lIAogIGZpbHRlcihkYXRlID49ICIyMDIzLTA0LTAxIiAmIGRhdGUgPCAiMjAyMy0wNC0wNiIpCgpnZ3Bsb3QobWFyY2gyMykgKwogIGdlb21fcG9pbnQoYWVzKGRhdGV0aW1lLG5ldF9rV2gpKQoKCmdncGxvdChtYXJjaDIzKSArCiAgZ2VvbV9wb2ludChhZXModGltZSxuZXRfa1doLCBjb2xvciA9IGZhY3RvcihkYXRlKSkpCgpgYGAKCgoKCg==